local extension = Package:new("sifu_heg_jin")
extension.extensionName = "sifu_heg"

local U = require "packages/utility/utility"
local S = require "packages/sifu_heg/SeaFunc"
extension.game_modes_whitelist = {"zhonger_heg_mode"}

Fk:loadTranslationTable{
  ["sifu_heg_jin"] = "扩展",
  ["jin_heg"] = "扩展包",
  ["jinh"] = "晋",
  ["@$Publishing"] = "明置",
  ["Published"] = "明置中",
}

--- 系列特色 --- 明置相关
local Pub = "@$Publishing" --- 明置Mark

--- 明置
---@param player ServerPlayer @ 执行者
---@param cards int[] @ 牌的id表
local function publish(player, cards)
  local room = player.room
  room:setPlayerMark(player, Pub, cards)
end

--- 判断牌是否明置
---@param player ServerPlayer @ 执行者
---@param id int @ 牌的id 
---@return bool
local function isPublished(player, id)
  local published_cards = player:getTableMark( Pub)
  return table.contains(published_cards, id)
end

--- 取消明置
---@param player ServerPlayer @ 执行者
---@param card int @ 牌的id
local function unpublish(player, card)
  local room = player.room
  if isPublished(player, card) then
    local cards = player:getTableMark( Pub)
    table.removeOne(cards, card)
    room:setPlayerMark(player, Pub, #cards > 0 and cards or 0)
  end
end

--- 离开手牌取消明置
local publish_refresher = fk.CreateTriggerSkill{
  name = "ze_publish_refresher",
  global = true,

  refresh_events = {fk.BeforeCardsMove},
  can_refresh = function(self, event, target, player, data)
    return true
  end,
  on_refresh = function(self, event, target, player, data)
    local published_cards = player:getTableMark(Pub)
    if table.find(player:getMarkNames(), function(name)
      return string.find(name, "KeepShowing")
    end) then
      published_cards = player:getCardIds("h")
    end
    if #published_cards ~= 0 then
      for _, move in ipairs(data) do
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerHand and isPublished(player, info.cardId) then
            table.removeOne(published_cards, info.cardId)
          end
        end
      end
      if #published_cards == 0 then
        player.room:setPlayerMark(player, Pub, 0)
      else
        player.room:setPlayerMark(player, Pub, published_cards)
      end
    end
  end
}
S.skillInfo(publish_refresher, "明置[失去]", "明置的牌已失去")
Fk:addSkill(publish_refresher)

local jin_heg__guozhao = General(extension, "jin_heg__guozhao", "wei", 3, 3, General.Female) --郭女王
local jin_heg__pianchong__amazingGraceSkill = fk.CreateActiveSkill{
  name = "jin_heg__pianchong__amazing_grace_skill",
  prompt = "#amazing_grace_skill",
  can_use = Util.GlobalCanUse,
  on_use = Util.GlobalOnUse,
  mod_target_filter = Util.TrueFunc,
  on_action = function(self, room, use, finished)
    local player = room:getPlayerById(use.from)
    if not finished then
      local toDisplay = player:getCardIds(Player.Hand)
      room:moveCardTo(toDisplay, Card.Processing, nil, fk.ReasonJustMove, "amazing_grace_skill", "", true, player.id)

      table.forEach(room.players, function(p)
        room:fillAG(p, toDisplay)
      end)

      use.extra_data = use.extra_data or {}
      use.extra_data.AGFilled = toDisplay
    else
      if use.extra_data and use.extra_data.AGFilled then
        table.forEach(room.players, function(p)
          room:closeAG(p)
        end)

        local toDiscard = table.filter(use.extra_data.AGFilled, function(id)
          return room:getCardArea(id) == Card.Processing
        end)

        if #toDiscard > 0 then
          if player.dead then
            room:moveCards({
              ids = toDiscard,
              toArea = Card.DiscardPile,
              moveReason = fk.ReasonPutIntoDiscardPile,
            })
          else
            room:moveCardTo(toDiscard, Card.PlayerHand, player, fk.ReasonJustMove, "amazing_grace_skill", "", true, player.id)
          end
        end
      end

      use.extra_data.AGFilled = nil
    end
  end,
  on_effect = function(self, room, effect)
    local to = room:getPlayerById(effect.to)
    if not (effect.extra_data and effect.extra_data.AGFilled and #effect.extra_data.AGFilled > 0) then
      return
    end

    local chosen = room:askForAG(to, effect.extra_data.AGFilled, false, "amazing_grace_skill")
    room:takeAG(to, chosen, room.players)
    room:obtainCard(effect.to, chosen, true, fk.ReasonPrey)
    table.removeOne(effect.extra_data.AGFilled, chosen)
  end,
}
Fk:addSkill(jin_heg__pianchong__amazingGraceSkill)
local jin_heg__pianchong = fk.CreateActiveSkill{
  name = "jin_heg__pianchong",
  target_num = 1,
  card_num = 0,
  prompt = "#jin_heg__pianchong-active",
  anim_type = "control",
  interaction = function()
    return UI.ComboBox {
      choices = {"draw1", "jin_heg__pianchong_equip"}
    }
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    if self.interaction.data == "draw1" then
      target:drawCards(1, self.name)
    else
      target:reset()
    end
    if target.dead or target:getHandcardNum() < #room.alive_players then return end
      room:loseHp(target, 1, self.name)
  end,
}
local jin_heg__zunwei = fk.CreateActiveSkill{
  name = "jin_heg__zunwei",
  frequency = Skill.Limited,
  prompt = "#jin_heg__zunwei-active",
  anim_type = "control",
  card_num = 0,
  target_num = 1,
  interaction = function()
    local choices, all_choices = {}, {}
    for i = 1, 3 do
      local choice = "jin_heg__zunwei"..tostring(i)
      table.insert(all_choices, choice)
      if Self:getMark(choice) == 0 then
        table.insert(choices, choice)
      end
    end
    return UI.ComboBox {choices = choices, all_choices = all_choices}
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    return self.interaction.data and #selected == 0 and to_select ~= Self.id
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local choice = self.interaction.data
    if choice == "jin_heg__zunwei1" then
      local x = math.min(target:getHandcardNum(), 5)
      if x > 0 then
        room:drawCards(player, x, self.name)
      end
    elseif choice == "jin_heg__zunwei2" then
      local subtypes = {
        Card.SubtypeWeapon,
        Card.SubtypeArmor,
        Card.SubtypeDefensiveRide,
        Card.SubtypeOffensiveRide,
        Card.SubtypeTreasure
      }
      local subtype
      local cards = {}
      local card
      while not (player.dead or target.dead) and
      #player.player_cards[Player.Equip] < #target.player_cards[Player.Equip] do
        while #subtypes > 0 do
          subtype = table.remove(subtypes, 1)
          if player:hasEmptyEquipSlot(subtype) then
            cards = table.filter(room.draw_pile, function (id)
              card = Fk:getCardById(id)
              return card.sub_type == subtype and U.canUseCardTo(room, player, player, card)
            end)
            if #cards > 0 then
              room:useCard{
                from = player.id,
                card = Fk:getCardById(cards[math.random(1, #cards)]),
              }
              break
            end
          end
        end
        if #subtypes == 0 then break end
      end
    elseif choice == "jin_heg__zunwei3" and player:isWounded() then
      local x = target.hp - player.hp
      if x > 0 then
      room:recover{
        who = player,
        num = math.min(player:getLostHp(), x),
        recoverBy = player,
        skillName = self.name}
      end
    end
    room:setPlayerMark(player, choice, 1)
  end,
}
jin_heg__guozhao:addSkill(jin_heg__pianchong)
jin_heg__guozhao:addSkill(jin_heg__zunwei)
Fk:loadTranslationTable{
  ["jin_heg__guozhao"] = "郭女王",
  ["#jin_heg__guozhao"] = "策出椒房",
  ["jin_heg__pianchong"] = "恭肃",
  [":jin_heg__pianchong"] = "出牌阶段限一次，你可以令一名角色摸一张牌或复原武将牌。若其手牌数不小于存活角色数，"..
  "其失去1点体力。",
  ["#jin_heg__pianchong-active"] = "发动 恭肃，选择一名角色",
  ["jin_heg__pianchong_equip"] = "复原武将牌",
  ["jin_heg__zunwei"] = "尊位",
  [":jin_heg__zunwei"] = "限定技，你可以选择一名其他角色并选择一项：1.摸X张牌（X为其手牌数且最多为5）；"..
  "2.随机使用牌堆中的装备牌至与该角色相同；3.将体力回复至与该角色相同。",
  ["#jin_heg__zunwei-active"] = "发动 尊位，选择一名其他角色并执行一项效果",
  ["jin_heg__zunwei1"] = "摸X张牌（X为其手牌数且最多为5）",
  ["jin_heg__zunwei2"] = "使用装备至与其相同",
  ["jin_heg__zunwei3"] = "回复体力至与其相同",
  ["$jin_heg__pianchong1"] = "得陛下怜爱，恩宠不衰。",
  ["$jin_heg__pianchong2"] = "谬蒙圣恩，光授殊宠。",
  ["$jin_heg__zunwei1"] = "处尊居显，位极椒房。",
  ["$jin_heg__zunwei2"] = "自在东宫，及即尊位。",
  ["~jin_heg__guozhao"] = "我的出身，不配为后？",
}

local caozhang = General(extension, "jin_heg__caozhang", "wei", 4)
caozhang:addSkill("ty_ex__jiangchi")
Fk:loadTranslationTable{
  ["jin_heg__caozhang"] = "曹彰",
  ["~jin_heg__caozhang"] = "子桓，你害我！",
}

local jin_heg__guanping = General(extension, "jin_heg__guanping", "shu", 4)
local jin_heg__longyin = fk.CreateTriggerSkill{
  name = "jin_heg__longyin",
  anim_type = "switch",
  switch_skill_name = "jin_heg__longyin",
  events = {fk.CardUsing, fk.CardResponding},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
    not data.card:isVirtual() and table.contains(data.card.skillNames, "jin_heg__longyin")
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if data.card.trueName == "duel" then
      local targets = TargetGroup:getRealTargets(data.tos)
      room:doIndicate(player.id, targets)
      for _, id in ipairs(targets) do
        local p = room:getPlayerById(id)
        if player.dead then return end
      end
    end
  end,

  refresh_events = {fk.PreCardUse},
  can_refresh = function(self, event, target, player, data)
    return target == player and data.card.trueName == "slash" and not data.card:isVirtual() and table.contains(data.card.skillNames, "jin_heg__longyin")
  end,
  on_refresh = function(self, event, target, player, data)
    data.extraUse = true
  end,
}
local jin_heg__longyin_filter = fk.CreateFilterSkill{
  name = "#jin_heg__longyin_filter",
  anim_type = "offensive",
  card_filter = function(self, card, player)
    if player:hasSkill(jin_heg__longyin) and card.type == Card.TypeBasic and
    table.contains(player.player_cards[Player.Hand], card.id) then
      if player:getSwitchSkillState("jin_heg__longyin", false) == fk.SwitchYang then
        return card.color == Card.Black
      else
        return card.color == Card.Red
      end
    end
  end,
  view_as = function(self, card, player)
    local name = "slash"
    if player:getSwitchSkillState("jin_heg__longyin", false) == fk.SwitchYang then
      name = "duel"
    end
    local c = Fk:cloneCard(name, card.suit, card.number)
    c.skillName = "jin_heg__longyin"
    return c
  end,
}
local jin_heg__longyin_targetmod = fk.CreateTargetModSkill{
  name = "#jin_heg__longyin_targetmod",
  bypass_times = function(self, player, skill, scope, card)
    return card.trueName == "slash" and table.contains(card.skillNames, "jin_heg__longyin") and scope == Player.HistoryPhase
  end,
}
jin_heg__longyin:addRelatedSkill(jin_heg__longyin_filter)
jin_heg__longyin:addRelatedSkill(jin_heg__longyin_targetmod)
jin_heg__guanping:addSkill(jin_heg__longyin)
Fk:loadTranslationTable{
  ["jin_heg__guanping"] = "关平",
  ["#jin_heg__guanping"] = "忠臣孝子",
  ["jin_heg__longyin"] = "龙吟",
  [":jin_heg__longyin"] = "转换技，锁定技，阳：你的黑色基本牌视为【决斗】；阴：你的红色基本牌视为无次数限制的【杀】。",
  ["#jin_heg__longyin_filter"] = "龙吟",
  ["$jin_heg__longyin1"] = "破阵杀敌，愿献犬马之劳！",
  ["$jin_heg__longyin2"] = "虎啸既响，龙吟当附！",
  ["~jin_heg__guanping"] = "父亲快走，孩儿断后……",
}

local jin_heg__zhangsong = General(extension, "jin_heg__zhangsong", "shu", 3)
local jin_heg__qiangzhi = fk.CreateTriggerSkill{
  name = "jin_heg__qiangzhi",
  anim_type = "defensive",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player == target and player.phase == Player.Draw
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local choices = {"cancel"}
    if player:isWounded() then table.insert(choices,1, "#jin_heg__qiangzhi2") end
    local choice = target.room:askForChoice(target, choices, self.name)
    if choice ~= "cancel" then
      self.cost_data = choice
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choice = self.cost_data
    if choice == "#jin_heg__qiangzhi1" then
      room:addPlayerMark(player, MarkEnum.AddMaxCards, 1)
      room:addPlayerMark(player, "jin_heg__qiangzhi_other-turn")
    else
      room:recover({ who = player,  num = 1, skillName = self.name })
      room:addPlayerMark(player, "jin_heg__qiangzhi_self-turn")
    end
  end,
}
local jin_heg__qiangzhi_prohibit = fk.CreateProhibitSkill{
  name = "#jin_heg__qiangzhi_prohibit",
  is_prohibited = function(self, from, to)
    return (from:getMark("jin_heg__qiangzhi_other-turn") > 0 and from ~= to) or (from:getMark("jin_heg__qiangzhi_self-turn") > 0 and from == to)
  end,
}
jin_heg__qiangzhi:addRelatedSkill(jin_heg__qiangzhi_prohibit)
jin_heg__zhangsong:addSkill(jin_heg__qiangzhi)
jin_heg__zhangsong:addSkill("xiantu")
Fk:loadTranslationTable{
  ["jin_heg__zhangsong"] = "张松",
  ["#jin_heg__zhangsong"] = "怀璧待凤仪",
  ["designer:jin_heg__zhangsong"] = "冷王无双",
  ["illustrator:jin_heg__zhangsong"] = "尼乐小丑",
  ["jin_heg__qiangzhi"] = "强识",
  [":jin_heg__qiangzhi"] = "摸牌阶段开始时，你可以回复1点体力，然后本回合你不能对自己使用牌。",
  ["#jin_heg__qiangzhi1"] = "手牌上限+1，本回合不能对其他角色用牌",
  ["#jin_heg__qiangzhi2"] = "回复1点体力，本回合不能对自己用牌",
  ["#jin_heg__qiangzhi_prohibit"] = "强识",
  ["$jin_heg__qiangzhi1"] = "容我过目，即刻咏来。",
  ["$jin_heg__qiangzhi2"] = "文书强识，才可博于运筹。",
  ["~jin_heg__zhangsong"] = "皇叔不听吾谏言，悔时晚矣！",
}

local zhuran = General(extension, "jin_heg__zhuran", "wu", 4)
local jin_heg__danshou = fk.CreateTriggerSkill{
  name = "jin_heg__danshou",
  mute = true,
  events = {fk.TargetConfirmed, fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 then
      if event == fk.TargetConfirmed then
        if target == player and data.card.type ~= Card.TypeEquip then
          local n = 0
          local events = player.room.logic:getEventsOfScope(GameEvent.UseCard, 999, function(e)
            local use = e.data[1]
            if use.card.type ~= Card.TypeEquip and table.contains(TargetGroup:getRealTargets(use.tos), player.id) then
              n = n + 1
            end
          end, Player.HistoryTurn)
          return n > 0
        end
      elseif event == fk.EventPhaseStart then
        return target.phase == Player.Finish and #player:getCardIds("he") >= target:getHandcardNum()
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TargetConfirmed then
      local n = 0
      local events = player.room.logic:getEventsOfScope(GameEvent.UseCard, 999, function(e)
        local use = e.data[1]
        if use.card.type ~= Card.TypeEquip and table.contains(TargetGroup:getRealTargets(use.tos), player.id) then
          n = n + 1
        end
      end, Player.HistoryTurn)
      if room:askForSkillInvoke(player, self.name, nil, "#jin_heg__danshou-draw:::"..n) then
        self.cost_data = n
        return true
      end
    else
      local n = target:getHandcardNum()+1
      local cards = {}
      local yes = false
      if n == 0 then
        if room:askForSkillInvoke(player, self.name, nil, "#jin_heg__danshou-trigger::"..target.id) then
          yes = true
        end
      else
        cards = room:askForDiscard(player, n, n, true, self.name, true, ".", "#jin_heg__danshou-damage::"..target.id..":"..n, true)
        if #cards == n then
          yes = true
        end
      end
      if yes then
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name)
    if event == fk.TargetConfirmed then
      room:notifySkillInvoked(player, self.name, "drawcard")
      room:setPlayerMark(player, "@jin_heg__danshou-turn", 0)
      player:drawCards(self.cost_data, self.name)
    else
      room:notifySkillInvoked(player, self.name, "offensive")
      room:throwCard(self.cost_data, self.name, player, player)
      if not target.dead then
        room:doIndicate(player.id, {target.id})
        room:damage{
          from = player,
          to = target,
          damage = 1,
          skillName = self.name,
        }
      end
    end
  end,
  refresh_events = {fk.TargetConfirmed},
  can_refresh = function(self, event, target, player, data)
    return target == player and data.card.type ~= Card.TypeEquip
    and player:hasSkill(self, true) and player:usedSkillTimes("jin_heg__danshou", Player.HistoryTurn) == 0
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local events = player.room.logic:getEventsOfScope(GameEvent.UseCard, 999, function(e)
      local use = e.data[1]
      return use.card.type ~= Card.TypeEquip and table.contains(TargetGroup:getRealTargets(use.tos), player.id)
    end, Player.HistoryTurn)
    room:setPlayerMark(player, "@jin_heg__danshou-turn", #events)
  end,
}
zhuran:addSkill(jin_heg__danshou)
Fk:loadTranslationTable{
  ["jin_heg__zhuran"] = "朱然",
  ["#jin_heg__zhuran"] = "不动之督",
  ["illustrator:jin_heg__zhuran"] = "F源",
  ["jin_heg__danshou"] = "胆守",
  [":jin_heg__danshou"] = "每回合限一次，当你成为基本牌或锦囊牌的目标后，你可以摸X张牌（X为你本回合成为基本牌或锦囊牌的目标次数）；"..
  "一名角色的结束阶段，若你本回合没有以此法摸牌，你可以弃置Y张牌（Y为其手牌数+1），对其造成1点伤害。",
  ["#jin_heg__danshou-draw"] = "胆守：你可以摸%arg张牌",
  ["#jin_heg__danshou-trigger"] = "胆守：你可以对 %dest 造成1点伤害",
  ["#jin_heg__danshou-damage"] = "胆守：你可以弃置%arg张牌，对 %dest 造成1点伤害",
  ["@jin_heg__danshou-turn"] = "胆守",
  ["$jin_heg__danshou1"] = "胆识过人而劲勇，则见敌无所畏惧",
  ["$jin_heg__danshou2"] = "胆守有余，可堪大任！",
  ["~jin_heg__zhuran"] = "义封一生……不负国家！",
}

local luotong = General(extension, "jin_heg__luotong", "wu", 3)
local aigi = fk.CreateTriggerSkill{
  name = "#renshi",
  anim_type = "drawcard",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if not (player:hasSkill(self) and player:isKongcheng() and player.phase ~= Player.NotActive) then return false end
    for _, move in ipairs(data) do
      if move.from == player.id then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerHand then
            return true
          end
        end
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local n = 0
    for _, move in ipairs(data) do
      if move.from == player.id then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerHand then
            n = n + 1
            n = 1
          end
        end
      end
    end
    local players = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, n, "#ze__qinzheng-invoke:::"..n, self.name)
    if #players > 0 then
      self.cost_data = players
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local targets = self.cost_data
    room:sortPlayersByAction(targets)
    for _, pid in ipairs(targets) do
      local p = room:getPlayerById(pid)
      if not p.dead then p:drawCards(1, self.name) end
    end
  end,
}
local ze__qinzheng = fk.CreateActiveSkill{
  name = "ze__qinzheng",
  anim_type = "support",
  card_num = 1,
  target_num = 1,
  prompt = "#aigi",
  can_use = function(self, player)
    return not player:isKongcheng()
  end,
  card_filter = function(self, to_select, selected)
    return #selected == 0 and Fk:currentRoom():getCardArea(to_select) == Player.Hand
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected == 0 and to_select ~= Self.id and Fk:currentRoom():getPlayerById(to_select):getMark("aigi-phase") == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:setPlayerMark(target, "aigi-phase", 1)
    room:moveCardTo(effect.cards[1], Card.PlayerHand, target, fk.ReasonGive, self.name, nil, false, player.id)
  end,
}
ze__qinzheng:addRelatedSkill(aigi)
luotong:addSkill(ze__qinzheng)
Fk:loadTranslationTable{
  ["jin_heg__luotong"] = "骆统",
  ["ze__qinzheng"] = "勤政",
  [":ze__qinzheng"] = "你的回合内，当你失去手牌后，若你没有手牌，则你可以令一名角色摸一张牌。出牌阶段每名角色限一次，你可以将一张手牌交给一名其他角色。",
  ["#renshi"] = "勤政",
  ["#aigi"] = "勤政：你可以将一张手牌交给一名其他角色",
  ["#ze__qinzheng-invoke"] = "勤政：你可令一名角色摸一张牌",
  ["$ze__qinzheng1"] = "夫国之有民，犹水之有舟，停则以安，扰则以危。",
  ["$ze__qinzheng2"] = "治疾及其未笃，除患贵其莫深。",
  ["~jin_heg__luotong"] = "臣统之大愿，足以死而不朽矣。",
}

local mark_name = "@$ze_yinsghi" -- 鹰视

--- 上标记
local function setUnvisableMark(player, mark)
  player:setMark(mark_name, mark)
  player:doNotify("SetPlayerMark", json.encode{ player.id, mark_name, mark})
end

local yingshi = fk.CreateTriggerSkill{
  name = "ze__yingshi",
  anim_type = "special",
  frequency = Skill.Compulsory,

  refresh_events = {fk.AfterCardsMove, fk.EventPhaseStart, fk.GeneralRevealed, fk.AfterPropertyChange, fk.EventPhaseEnd},
  can_refresh = function(self, event, target, player, data)
    return player:hasSkill(self) and player.phase == Player.Play and not player:isFakeSkill(self)
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark(mark_name)
    local toView = table.slice(room.draw_pile, 1, player.maxHp +1)
    if event == fk.EventPhaseEnd then
      setUnvisableMark(player, 0)
    elseif not mark.value or toView ~= mark.value then
      if table.contains({fk.EventPhaseStart}, event) then
        player:broadcastSkillInvoke(self.name)
      end
      setUnvisableMark(player, toView)
    end
  end,
}
S.skillInfo(yingshi, "鹰视",
  "锁定技，你的出牌阶段内，牌堆顶的X张牌对你可见（X为你的体力上限）。",
  {"鹰扬千里，明察秋毫。","鸢飞戾天，目入百川。"}
)

Fk:loadTranslationTable{
  [mark_name] = "鹰视",
}

local xiongzhi = fk.CreateActiveSkill{
  name = "ze__xiongzhi",
  anim_type = "offensive",
  frequency = Skill.Limited,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_num = 0,
  card_filter = Util.FalseFunc,
  target_num = 0,
  target_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    while true do
      if player.dead then return end
      local id = room:getNCards(1)
      room:moveCards({
        ids = id,
        toArea = Card.Processing,
        moveReason = fk.ReasonJustMove,
        skillName = self.name,
      })
      local card = Fk:getCardById(id[1], true)
      local tos = U.getDefaultTargets(player, card, true)
      if tos then
        local propompt = "#xiongzhi-use:::"..Fk:translate(card.name)
        local extra_data = { card = id[1], bypass_times = true }
        local _, ret = room:askForUseActiveSkill(player, "assign_cards_use", propompt, false, extra_data)
        if ret and ret.targets then
          tos = ret.targets
        end
      end
      if tos then
        room:useCard({
          card = card,
          from = player.id,
          tos = table.map(tos, function(p) return {p} end) ,
          skillName = self.name,
          extraUse = true,
        })
      else
        room:delay(800)
        room:moveCards({
          ids = id,
          fromArea = Card.Processing,
          toArea = Card.DrawPile,
          moveReason = fk.ReasonJustMove,
        })
        return
      end
    end
  end,
}
S.skillInfo(xiongzhi, "雄志",
  "限定技，出牌阶段，你可以连续展示并使用牌堆顶的牌，直到牌堆顶的牌不能被使用。",
  {"烈士雄心，志存高远。","乱世之中，唯我司马！"}
)

Fk:loadTranslationTable{
  ["#xiongzhi-use"] = "雄志：选择【%arg】的目标，使用【%arg】"
}

local quanbian = fk.CreateTriggerSkill{
  name = "ze__quanbian",
  anim_type = "drawcard",
  events = {fk.CardUsing, fk.CardResponding},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and player.phase == Player.Play and data.card.suit ~= Card.NoSuit and
      U.IsUsingHandcard(player, data) then
      local card_suit = data.card.suit
      local room = player.room
      local logic = room.logic
      local current_event = logic:getCurrentEvent()
      local mark_name = "quanbian_" .. data.card:getSuitString() .. "-phase"
      local mark = player:getMark(mark_name)
      if mark == 0 then
        logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
          local use = e.data[1]
          if use.from == player.id and use.card.suit == card_suit then
            mark = e.id
            room:setPlayerMark(player, mark_name, mark)
            return true
          end
          return false
        end, Player.HistoryPhase)
        logic:getEventsOfScope(GameEvent.RespondCard, 1, function(e)
          local use = e.data[1]
          if use.from == player.id and use.card.suit == card_suit then
            mark = math.max(e.id, mark)
            room:setPlayerMark(player, mark_name, mark)
            return true
          end
          return false
        end, Player.HistoryPhase)
      end
      return mark == current_event.id
    end
  end,
  on_trigger = function(self, event, target, player, data)
    local mark = player:getMark("@quanbian-phase")
    if mark == 0 then mark = {} end
    table.insert(mark, data.card:getSuitString(true))
    player.room:setPlayerMark(player, "@quanbian-phase", mark)
    self:doCost(event, target, player, data)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = room:getNCards(player.maxHp)
    local handcards = player:getCardIds("h")
    local to_ex = U.askForExchange(player, "Top", "hand_card", cards, handcards, "#quanbianze-exchange", 1)
    if #to_ex == 0 then return end
    local index = 0
    local cardA = table.find(cards, function(id)
      index = index + 1
      return table.contains(to_ex, id)
    end)
    local cardB = table.find(to_ex, function(id)
      return id ~= cardA
    end)
    room:moveCards({
      ids = cards,
      toArea = Card.Processing,
      skillName = self.name,
      moveReason = fk.ReasonExchange,
      proposer = player.id,
      moveVisible = false
    }, {
      ids = {cardB},
      from = player.id,
      toArea = Card.Processing,
      skillName = self.name,
      moveReason = fk.ReasonExchange,
      proposer = player.id,
      moveVisible = false
    })
    local moveInfos = {}
    if room:getCardArea(cardA) == Card.Processing then
      if player.dead then
        table.insert(moveInfos, {
          ids = {cardA},
          fromArea = Card.Processing,
          toArea = Card.DiscardPile,
          moveReason = fk.ReasonExchange,
          proposer = player.id,
          skillName = self.name
        })
      else
        table.insert(moveInfos, {
          ids = {cardA},
          fromArea = Card.Processing,
          to = player.id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonExchange,
          proposer = player.id,
          skillName = self.name,
          moveVisible = false
        })
      end
    end
    table.remove(cards, index)
    table.insert(cards, index, cardB)
    cards = table.reverse(cards)
    cards = table.filter(cards, function(id)
      return room:getCardArea(id) == Card.Processing
    end)
    if #cards > 0 then
      table.insert(moveInfos, {
        ids = cards,
        toArea = Card.DrawPile,
        moveReason = fk.ReasonExchange,
        proposer = player.id,
        skillName = self.name,
        moveVisible = false
      })
    end
    if #moveInfos > 0 then
      room:moveCards(table.unpack(moveInfos))
    end
  end,
}
S.skillInfo(quanbian, "权变",
  "当你于出牌阶段首次使用或打出一种花色的手牌时，你可从用一张手牌替换牌堆顶X张牌中的一张（X为你的体力上限）。",
  {"筹权谋变，步步为营。","随机应变，谋国窃权。"}
)

Fk:loadTranslationTable{
  ["#quanbianze-exchange"] = "权变：可以用一张手牌替换其中的一张牌"
}

local simayi = General(extension, "jin_heg__simayi", "qun", 4)  -- 司马懿
S.generalInfo(simayi, "司马懿", "通达权变", "", "", "", "六道目", "虎入骷冢，司马难兴。")
simayi:addSkill(yingshi)
simayi:addSkill(xiongzhi)
simayi:addSkill(quanbian)
simayi:addCompanions("jin_heg__simashi")

--- 司马师
local yimie = fk.CreateTriggerSkill{
  name = "ze__yimie",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  refresh_events = {fk.EnterDying},
  can_refresh = function(self, event, target, player, data)
    return player:hasSkill(self) and player.phase ~= Player.NotActive and table.contains(player.player_skills, self)
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:notifySkillInvoked(player, self.name)
    player:broadcastSkillInvoke(self.name)
  end,
}
S.skillInfo(yimie, "夷灭",
  "锁定技，你的回合内，处于濒死状态的角色不能使用【桃】。",
  {"汝大逆不道，当死无赦！","斩草除根，灭其退路！"}
)

local yimie_prohibit = fk.CreateProhibitSkill{
  name = "#yimie_prohibit",
  prohibit_use = function(self, player, card)
    if card.name == "peach" and player.dying then
      local cfilter = function(p)
        return p.phase ~= Player.NotActive and p:hasSkill(yimie) and table.contains(p.player_skills, yimie)
      end
      return table.find(Fk:currentRoom().alive_players, cfilter)
    end
  end,
}
S.skillInfo(yimie_prohibit, "夷灭", "处于濒死状态的角色不能使用【桃】。")
yimie:addRelatedSkill(yimie_prohibit)

local tairan = fk.CreateTriggerSkill{
  name = "ze__tairan",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.TurnEnd, fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if event == fk.TurnEnd then
        return player:getHandcardNum() < player.maxHp
      elseif player.phase == Player.Play then
        local cfilter = function(id)
          local card = Fk:getCardById(id)
          return card:getMark("@@ze_tairan_Pub-inhand") > 0 and not player:prohibitDiscard(card)
        end
        return table.find(player:getCardIds("h"), cfilter)
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnEnd then
      local num = player.maxHp - player:getHandcardNum()
      if num > 0 then
        player:drawCards(num, self.name)
        local all_cards = player:getCardIds("h")
        local cards = table.filter(all_cards, function(id)
          if not isPublished(player, id) then
            return true
          end
        end)
        num = math.min(#cards, num)
        local selected, _ = U.askforChooseCardsAndChoice(player, cards, {"OK"}, self.name, "#tairanze-choose:::"..num, nil, num, num, all_cards)
        publish(player, selected)
        for _, id in ipairs(selected) do
          local card = Fk:getCardById(id)
          room:setCardMark(card, "@@ze_tairan_Pub-inhand", 1)
        end
      end
    else
      local cfilter = function(id)
        local card = Fk:getCardById(id)
        return card:getMark("@@ze_tairan_Pub-inhand") > 0 and not player:prohibitDiscard(card)
      end
      if not player.dead then
        local cards = table.filter(player:getCardIds(Player.Hand), cfilter)
        if #cards == 0 then return end
        room:throwCard(cards, self.name, player, player)
      end
    end
  end,
}
S.skillInfo(tairan, "泰然",
  "锁定技，回合结束时，你摸X张牌（X为你的体力上限-手牌数），明置等量张手牌；出牌阶段开始时，你弃置以此法明置的牌。",
  {"撼山易，撼我司马氏难。","云卷云舒，处之泰然。"}
)

Fk:loadTranslationTable{
  ["#tairanze-choose"] = "泰然：请选 %arg 张手牌明置",
  ["@@ze_tairan_Pub-inhand"] = "泰然"
}

local simashi = General(extension, "jin_heg__simashi", "qun", 4) -- 司马师
S.generalInfo(simashi, "司马师", "摧坚荡异", "", "", "", "拉布拉卡", "子上，这是为兄给你打下的江山……")
simashi:addSkill(yimie)
simashi:addSkill(tairan)
return extension
